`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    08:34:22 11/21/2012 
// Design Name: 
// Module Name:    Mfms 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module Mfsm(clk_i,rst_i,turno_o,inicio_i,comienza_turno_o,gano_o,sal_j_i,sal_o_i,write_o,read_o,comparar_o,adre_a_o,adre_b_o,termina_mem_i,cambia_turno_i,listo_leer_i,elegir_pos_i,posicion_i,enviar_listo_o,confirmar_i,state
    );
	input clk_i,rst_i,inicio_i,termina_mem_i,listo_leer_i,elegir_pos_i,confirmar_i,cambia_turno_i;
	input [2:0] posicion_i;
	input [1:0] sal_j_i,sal_o_i;
	output turno_o,write_o,read_o,comparar_o,comienza_turno_o,enviar_listo_o;
	output [1:0] gano_o;
	output [2:0] adre_a_o,adre_b_o;
	output [3:0] state;

	reg turno_o = 0;
	reg comienza_turno_o = 0;
	reg [2:0] adre_a_o = 0;
	reg [2:0] adre_b_o = 0;
	reg [1:0] gano_o = 0;
	reg write_o = 0;
	reg read_o = 0;
	reg comparar_o = 0;
	reg [3:0] cant_barcos_j = 10;
	reg [3:0] cant_barcos_o = 10;
	reg enviar_listo_o = 0;
	reg bloqueo = 0;
	
	parameter state0 = 4'b0000;
   parameter state1 = 4'b0001;
   parameter state2 = 4'b0010;
   parameter state3 = 4'b0011;
   parameter state4 = 4'b0100;
   parameter state5 = 4'b0101;
	parameter state6 = 4'b0110;
   parameter state7 = 4'b0111;
	parameter state8 = 4'b1000;
   parameter state9 = 4'b1001;


   reg [3:0] state = state0;

   always@(posedge clk_i)
      if (rst_i) begin
         state <= state0;
			turno_o <= 0;
      end
      else
         case (state)
            state0 : begin
               if (inicio_i) begin
                  state <= state1;
					end
               else
                  state <= state0;
            end
            state1 : begin
					if (termina_mem_i) begin
						write_o <= 0;
						turno_o <= 0;
                  state <= state2;
					end
					else if (cambia_turno_i) begin
						turno_o <= 1;
						state <= state1;
					end
               else begin
						write_o <= 1;
                  state <= state1;
					end
            end
            state2 : begin
					enviar_listo_o <= 1;
					if (elegir_pos_i) begin
						adre_b_o <= posicion_i;
						state <= state3;
					end
					else 
						state <= state2;
				end
				state3 : begin
					if (elegir_pos_i && confirmar_i) begin
						adre_a_o <= posicion_i;
						bloqueo<=0;
						comparar_o <= 1;
						state <= state4;
					end
					else 
						state <= state3;
				end
				state4 : begin 
					comparar_o <= 0;
					enviar_listo_o <= 0;
					state <= state5;
				end
            state5 : begin
					enviar_listo_o <= 0;
					read_o<=1;
					state <= state6;
            end
				state6 : begin
					if (cant_barcos_o==0) begin
						gano_o <= 2;
						adre_a_o<=0;
						adre_b_o<=0;
						read_o<=0;
                  state <= state0;
					end
					else if (sal_o_i==1) begin
						cant_barcos_o<=cant_barcos_o-1;
						state <= state6;
					end 
					else begin
						turno_o<=1;
						read_o<=0;
						state <= state7;
					end
            end
				state7 : begin
					if (listo_leer_i) begin
						comparar_o<=1;
						comienza_turno_o <= 0;
						state <= state8;
					end
               else begin
						comienza_turno_o <= 1;
                  state <= state7;
					end
            end
				state8 : begin
					comparar_o<=0;
					read_o<=1;
					state <= state9;
            end
				state9 : begin
					if (cant_barcos_j==0) begin
						gano_o <= 1;
						adre_a_o<=0;
						adre_b_o<=0;
						read_o<=0;
                  state <= state0;
					end
					else if (sal_j_i==1) begin
						cant_barcos_j<=cant_barcos_j-1;
						state <= state9;
					end 
					else begin
						turno_o<=0;
						state <= state2;
						read_o<=0;
					end
            end
			endcase
endmodule
